package gwall.cloud.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * TODO 优化
 **/
@Slf4j
public abstract class IfyouHttpUtils {

    /**
     * get请求
     * URL 不带参数
     */
    public static String doGet(String url, Map<String, String> paramMap) throws Exception {

        // 组装URL
        if (MapUtils.isNotEmpty(paramMap)) {
            StringBuilder builder = new StringBuilder();
            builder.append(url).append("?");
            paramMap.forEach((key, val) -> builder.append(key).append("=").append(val).append("&"));
            url = builder.substring(0, builder.length() - 1);
        }

        RequestConfig requestConfig = getRequestConfig();
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);

        String result;
        try (CloseableHttpResponse httpResponse = httpclient.execute(httpGet)) {

            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                result = EntityUtils.toString(httpResponse.getEntity());

                log.info("[doGet] exit, result = {}", result);
                return result;
            }
        } catch (Exception e) {
            log.error("[doGet] throw Exception, e = ", e);
        }

        return null;
    }

    /**
     * 组装配置信息
     */
    private static RequestConfig getRequestConfig() {
        return RequestConfig.custom()
                //毫秒
                .setSocketTimeout(60 * 1000)
                //毫秒 连接超时时间
                .setConnectTimeout(5000)
//                //毫秒  连接池获取连接超时时间
//                .setConnectionRequestTimeout(2000)
                .build();
    }

    public static String doPost(String url, String jsonString) throws Exception {
        log.info("[doPost] enter, url = {}, jsonString = {}", url, jsonString);

        int timeout = 2400 * 1000;

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(timeout)
                .setConnectionRequestTimeout(timeout)
                .setSocketTimeout(timeout)
                .setRedirectsEnabled(true).build();

        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/json");

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            httpPost.setEntity(new StringEntity(jsonString, ContentType.create("application/json", "utf-8")));

            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                int statusCode = response.getStatusLine().getStatusCode();
                log.info("[doPost] start, StatusCode = {}", statusCode);

                if (statusCode == 200) {
                    String result = EntityUtils.toString(response.getEntity());

                    log.info("[doPost] exit, result = {}", result);
                    return result;
                }
            }
        }

//        // TODO 替换
//        Map<String, String> headers = new HashMap<>();
//        headers.put("Content-Type", "application/json");
//        doPost(url, jsonString, headers);

        log.info("[doPost] exit, result is null");
        return null;
    }

    public static String doPost(String url, String jsonString, Map<String, String> headers) throws Exception {
        log.info("[doPost] enter, url = {}, jsonString = {}, headers = {}", url, jsonString, headers);

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(2400 * 1000).setConnectionRequestTimeout(2400 * 1000)
                .setSocketTimeout(2400 * 1000).setRedirectsEnabled(true).build();

        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        if (!CollectionUtils.isEmpty(headers)) {
            for (Map.Entry<String, String> e : headers.entrySet()) {
                httpPost.setHeader(e.getKey(), e.getValue());
            }
        }

        if (!StringUtils.isEmpty(jsonString)) {
            HttpEntity postEntity = new StringEntity(jsonString, "UTF-8");
            httpPost.setEntity(postEntity);
        }

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                int statusCode = response.getStatusLine().getStatusCode();
                log.info("[doPost] start, StatusCode = {}", statusCode);

                if (statusCode == 200) {
                    String result = EntityUtils.toString(response.getEntity());

                    log.info("[doPost] exit, result = {}", result);
                    return result;
                } else {
                    log.error("[doPost] start, not 200, response = {}", IfyouJsonUtils.toJson(response));
                }
            }
        }

        log.info("[doPost] exit, result is null");
        return null;
    }

}